/*=============================================================================
	stdafx.cpp: Cry Render support precompiled header generator.
	Copyright 2001 Crytek Studios. All Rights Reserved.

	Revision history:
		* Created by Honitch Andrey

=============================================================================*/

#ifndef __STDAFX_H__
#define __STDAFX_H__

#pragma once

#if (defined(PS3) || defined(CAFE)) && !defined(__SPU__) && !defined(_RELEASE)
//  #define DO_RENDERLOG
  #define DO_RENDERSTATS
#endif

#if !defined(_RELEASE)
# define RENDERER_ENABLE_BREAK_ON_ERROR 0
#endif 
#if !defined(RENDERER_ENABLE_BREAK_ON_ERROR)
# define RENDERER_ENABLE_BREAK_ON_ERROR 0
#endif
#if RENDERER_ENABLE_BREAK_ON_ERROR
# include <winerror.h>
namespace detail 
{
	const char* ToString(long const hr);
	bool CheckHResult(long const hr, bool breakOnError, const char* file, const int line);
}
//# undef FAILED
//# define FAILED(x) (detail::CheckHResult((x), false, __FILE__, __LINE__)) 
# define CHECK_HRESULT(x) (detail::CheckHResult((x), true, __FILE__, __LINE__)) 
#else
# define CHECK_HRESULT(x) (void)(x)
#endif 

// BUFFER_ENABLE_DIRECT_ACCESS
// stores pointers to actual backing storage of vertex buffers. Can only be used on architectures 
// that have a unified memory architecture and further guarantee that buffer storage does not change 
// on repeated accesses. Currently only enabled on PS3 and XENON

// BUFFER_NO_LOCK_ON_UPDATE
// Updates storage contents of buffers directly by using the extracted backing storage, therefore 
// requiring BUFFER_ENABLE_DIRECT_ACCESS to be supported. Currently disabled as benefits are unclear. 
// Note: The codepath might be declared obsolete and removed completely at some later stage. 

#ifndef BUFFER_ENABLE_DIRECT_ACCESS
# define BUFFER_ENABLE_DIRECT_ACCESS 0
#endif 
#ifndef BUFFER_NO_LOCK_ON_UPDATE
# define BUFFER_NO_LOCK_ON_UPDATE 0 
#endif 
#if BUFFER_ENABLE_DIRECT_ACCESS && (defined(WIN32) || defined(WIN64))
# error BUFFER_ENABLE_DIRECT_ACCESS is not supported on windows platforms
#endif 
#if BUFFER_NO_LOCK_ON_UPDATE && !BUFFER_ENABLE_DIRECT_ACCESS
# error BUFFER_NO_LOCK_ON_UPDATE can only be used with BUFFER_ENABLE_DIRECT_ACCESS
#endif 

// Incompatible Streams that are configured by default should be excluded here
#if defined (DIRECT3D9)
# define ENABLE_NORMALSTREAM_SUPPORT 0
#endif 


//#define DEFINE_MODULE_NAME "CryRender9"

// enable support for baked meshes and decals on PC
#if !defined(XENON) && !defined(PS3)
#define RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT
#define TEXTURE_GET_SYSTEM_COPY_SUPPORT
#endif

#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#endif //_DEBUG

#undef USE_STATIC_NAME_TABLE
#define USE_STATIC_NAME_TABLE

#if !defined(_RELEASE) && !defined(IS_CRYDEV) // don't enable frame profiler on free sdk!
#define ENABLE_FRAME_PROFILER
	#ifndef XENON  // Timers can cause deadlocks during concurrent device accesses of video thread
		#define ENABLE_SIMPLE_GPU_TIMERS
	#endif
#endif

#ifdef ENABLE_FRAME_PROFILER
#	define PROFILE 1
#	define ENABLE_FRAME_PROFILER_LABELS
#endif

#if !defined(XENON) && !defined(PS3)

	#ifdef ENABLE_FRAME_PROFILER_LABELS
		// This is need for D3DPERF_ functions
		#pragma comment(lib, "d3d9.lib")
	#endif

#endif

#include <CryModuleDefs.h>

#undef eCryModule
#define eCryModule eCryM_Render

#if __HAS_SSE__
// <fvec.h> includes <assert.h>, include it before platform.h
#include <fvec.h>
#define CONST_INT32_PS(N, V3, V2, V1, V0) \
  const _MM_ALIGN16 int _##N[] = { V0, V1, V2, V3 }; /*little endian!*/ \
  const F32vec4 N = _mm_load_ps((float*)_##N);
#endif

#include <platform.h>
#include <CrySizer.h>

#if defined(_CPU_SSE) && !defined(WIN64)
#define __HAS_SSE__ 1
#endif

#define MAX_REND_RECURSION_LEVELS 2

#ifdef STRIP_RENDER_THREAD
	#define m_nCurThreadFill 0
	#define m_nCurThreadProcess 0
#endif

#ifdef STRIP_RENDER_THREAD
	#define ASSERT_IS_RENDER_THREAD(rt)
	#define ASSERT_IS_MAIN_THREAD(rt)
#else
	#define ASSERT_IS_RENDER_THREAD(rt) assert((rt)->IsRenderThread());
	#define ASSERT_IS_MAIN_THREAD(rt) assert((rt)->IsMainThread());
#endif

//#define ASSERT_IN_SHADER( expr ) assert( expr );
#define ASSERT_IN_SHADER( expr )

#if defined (NULL_RENDERER) || defined (XENON) || defined(PS3) || defined(CAFE)
#define EXCLUDE_SQUISH_SDK
#endif

#define _USE_MATH_DEFINES
#include MATH_H

#ifdef WIN32
#include <winsock2.h>
#endif

// nvDXTLibrary
#if (defined(WIN32) || defined(WIN64)) && !defined(NULL_RENDERER)
#define USE_NV_DXT_LIB
#endif

// jpeg support
#if (defined(WIN32) || defined(WIN64)) && !defined(NULL_RENDERER)
#define USE_JPEG_LIB
#endif

// nv API
#if (defined(WIN32) || defined(WIN64)) && defined(DIRECT3D10)
#define USE_NV_API
#endif

// windows desktop API available for usage
#if defined(WIN32) || defined(WIN64) || defined(XENON)
#define WINDOWS_DESKTOP_API
#endif

#if defined(WIN32) || defined(WIN64)
#define USE_DXUT
#endif

#if defined(WIN32) || defined(WIN64) || defined(PS3)
#define USE_D3DX
#endif

#if defined(gringo) && (!defined(RELEASE) || defined(ENABLE_PROFILING_CODE))
#define USE_PIX_gringo
#endif

#if !defined(CRY_USE_GCM) && !defined(CRY_USE_GX2)
# if defined (DIRECT3D9)
// Direct3D9 includes
#  include <d3d9.h>
#  ifdef USE_D3DX
#   include <d3dx9.h>
#  endif
# else
#  if !defined(LINUX)
#  include <d3d9types.h>
#  include <d3d9caps.h>
#  endif
# endif
#endif

#if defined (DIRECT3D9) || defined (DIRECT3D10)

// Direct3D11 includes
#if !defined(XENON)
#if defined(CRY_USE_GCM)
#include "XRenderD3D9/DXPS/CCryDXPSMisc.hpp"
#include "XRenderD3D9/DXPS/CCryDXPSRenderer.hpp"
#include "XRenderD3D9/DXPS/DXPSGI/CCryDXPSGI.hpp"
#elif defined(CRY_USE_GX2)
	#include "XRenderD3D9/DXCAFE/CCryDXCafeMisc.hpp"
	#include "XRenderD3D9/DXCAFE/CCryDXCafeRenderer.hpp"
	#include "XRenderD3D9/DXCAFE/DXCafeGI/CCryDXCafeGI.hpp"
#else

//#include "dxgi.h"
#include <d3d11.h>

#if defined(USE_DXUT) || defined(USE_D3DX)
#include <d3dx9.h> // still needed on PC for DXUT
#include <d3dx11.h> // still needed on PC for texture creation and compilation
#endif

#endif
#endif
#elif defined (NULL_RENDERER) && defined(WIN32)
#include "windows.h"
#endif

#if !defined(XENON) && !defined(PS3) && !defined(gringo)
#	if defined(WIN32) || defined(WIN64)
#		define SUPPORT_DEVICE_INFO_MSG_PROCESSING
#	endif
#endif

#include "CryThread.h"

//////////////////////////////////////////////////////////////////////////
// XBOX specific defines for Renderer.
//////////////////////////////////////////////////////////////////////////

#if defined (DIRECT3D9)
#define Direct3D                         IDirect3D9
#define D3DDevice                        IDirect3DDevice9
#define D3DDeviceContext                 IDirect3DDevice9
#define D3DVertexDeclaration             IDirect3DVertexDeclaration9
#define D3DVertexShader                  IDirect3DVertexShader9
#define D3DPixelShader                   IDirect3DPixelShader9
#define D3DBaseTexture                   IDirect3DBaseTexture9
#define D3DTexture                       IDirect3DTexture9
#define D3DVolumeTexture                 IDirect3DVolumeTexture9
#define D3DCubeTexture                   IDirect3DCubeTexture9
#define D3DVertexBuffer                  IDirect3DVertexBuffer9
#define D3DIndexBuffer                   IDirect3DIndexBuffer9
#define D3DBuffer                        IDirect3DResource9
#define D3DSurface                       IDirect3DSurface9
#define D3DDepthSurface                  IDirect3DSurface9
#define D3DQuery                         IDirect3DQuery9
#define D3DViewPort                      D3DVIEWPORT9
#define D3DFormat                        D3DFORMAT
#define D3DShaderResource                (void *)
#define D3DPrimitiveType                 D3DPRIMITIVETYPE
inline bool operator != (const D3DVIEWPORT9& v0, const D3DVIEWPORT9& v1)
{
  if (v0.X!=v1.X || v0.Y!=v1.Y || v0.Width!=v1.Width || v0.Height != v1.Height || v0.MinZ!=v1.MinZ || v0.MaxZ!=v1.MaxZ)
    return true;
  return false;
}
#elif defined (DIRECT3D10)
#define Direct3D                         IDXGIAdapter
#define D3DDevice                        ID3D11Device
#define D3DDeviceContext                 ID3D11DeviceContext
#define D3DVertexDeclaration             ID3D11InputLayout
#define D3DVertexShader                  ID3D11VertexShader
#define D3DPixelShader                   ID3D11PixelShader
#define D3DBaseTexture                   ID3D11Resource
#define D3DTexture                       ID3D11Texture2D
#define D3DVolumeTexture                 ID3D11Texture3D
#define D3DCubeTexture                   ID3D11Texture2D
#define D3DVertexBuffer                  ID3D11Buffer
#define D3DShaderResource                ID3D11ShaderResourceView
#define D3DIndexBuffer                   ID3D11Buffer
#define D3DBuffer                        ID3D11Buffer
#define D3DSurface                       ID3D11RenderTargetView
#define D3DDepthSurface                  ID3D11DepthStencilView
#define D3DQuery                         ID3D11Query
#define D3DViewPort                      D3D11_VIEWPORT
#define D3DFormat                        DXGI_FORMAT
#define D3DPrimitiveType                 D3D11_PRIMITIVE_TOPOLOGY
#define D3DBlob                          ID3D10Blob

#ifndef gringo
// all D3D10 blob related functions and struct will be deprecated in next DirectX APIs
// and replaced with regular D3DBlob counterparts
#define D3DCreateBlob										 D3D10CreateBlob
#endif

const int32 g_nD3D10MaxSupportedSubres = (6 * 15);
//////////////////////////////////////////////////////////////////////////
#else
#define D3DFormat                        int
#endif // XENON
//////////////////////////////////////////////////////////////////////////

#define USAGE_WRITEONLY 8

//////////////////////////////////////////////////////////////////////////
// Linux specific defines for Renderer.
//////////////////////////////////////////////////////////////////////////

#if defined(_AMD64_) && !defined(LINUX)
#include <io.h>
#endif


/////////////////////////////////////////////////////////////////////////////
// STL //////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

#include <vector>
#include <list>
#include <map>
#include <set>
#include <algorithm>
#include <memory>

#define SIZEOF_ARRAY(arr) (sizeof(arr)/sizeof((arr)[0]))

#ifndef SAFE_DELETE_VOID_ARRAY
#define SAFE_DELETE_VOID_ARRAY(p)	{ if(p) { delete[] ((char*)p);		(p)=NULL; } }
#endif

#ifdef DEBUGALLOC

#include <crtdbg.h>
#define DEBUG_CLIENTBLOCK new( _NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_CLIENTBLOCK

// memman
#define   calloc(s,t)       _calloc_dbg(s, t, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   malloc(s)         _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   realloc(p, s)     _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)

#endif

#include <CryName.h>
#include "Common/CryNameR.h"

#define	MAX_TMU 16
#define	MAX_STREAMS 16

//! Include main interfaces.
#include <ICryPak.h>
#include <IProcess.h>
#include <ITimer.h>
#include <ISystem.h>
#include <ILog.h>
#include <IConsole.h>
#include <IRenderer.h>
#include <IStreamEngine.h>
#include <CrySizer.h>
#include <smartptr.h>
#include <CryArray.h>
#include <PoolAllocator.h>

#include <CryArray.h>

enum eRenderPrimitiveType
{
#if defined(DIRECT3D9)
	eptTriangleList = D3DPT_TRIANGLELIST,
	eptTriangleStrip = D3DPT_TRIANGLESTRIP,
	eptLineList = D3DPT_LINELIST,
	eptLineStrip = D3DPT_LINESTRIP,
	eptPointList = D3DPT_POINTLIST,
#elif defined(DIRECT3D10)
	eptTriangleList = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
	eptTriangleStrip = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
	eptLineList = D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
	eptLineStrip = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
	eptPointList = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
#elif defined(NULL_RENDERER)
	eptTriangleList,
	eptTriangleStrip,
	eptLineList,
	eptLineStrip,
	eptPointList,
#endif



#if defined(DIRECT3D10) && !defined(PS3) && !defined(CAFE)
	ept3ControlPointPatchList = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
#endif

	// non-real primitives, used for logical batching
	eptHWSkinGroups = 0x3f
};

inline eRenderPrimitiveType GetInternalPrimitiveType(PublicRenderPrimitiveType t)
{
	switch (t)
	{
	case prtTriangleList: default: return eptTriangleList;
	case prtTriangleStrip: return eptTriangleStrip;
	case prtLineList: return eptLineList;
	case prtLineStrip: return eptLineStrip;
	}
}





// Interfaces from the Game
extern ILog     *iLog;
extern IConsole *iConsole;
extern ITimer   *iTimer;
extern ISystem  *iSystem;

template <class Container>
unsigned sizeOfV (Container& arr)
{
  int i;
  unsigned size = 0;
  for (i=0; i<(int)arr.size(); i++)
  {
    typename Container::value_type& T = arr[i];
    size += T.Size();

  }
  size += (arr.capacity()-arr.size())*sizeof(typename Container::value_type);
  return size;
}
template <class Container>
unsigned sizeOfA (Container& arr)
{
  int i;
  unsigned size = 0;
  for (i=0; i<arr.size(); i++)
  {
    typename Container::value_type& T = arr[i];
    size += T.Size();

  }
  return size;
}
template <class Map>
unsigned sizeOfMap (Map& map)
{
  unsigned size = 0;
  for (typename Map::iterator it=map.begin(); it!=map.end(); it++)
  {
    typename Map::mapped_type& T = it->second;
    size += T.Size();
  }
  size += map.size() * sizeof(stl::MapLikeStruct);
  return size;
}
template <class Map>
unsigned sizeOfMapStr (Map& map)
{
  unsigned size = 0;
  for (typename Map::iterator it=map.begin(); it!=map.end(); it++)
  {
    typename Map::mapped_type& T = it->second;
    size += T.capacity();
  }
  size += map.size() * sizeof(stl::MapLikeStruct);
  return size;
}
template <class Map>
unsigned sizeOfMapP (Map& map)
{
  unsigned size = 0;
  for (typename Map::iterator it=map.begin(); it!=map.end(); it++)
  {
    typename Map::mapped_type& T = it->second;
    size += T->Size();
  }
  size += map.size() * sizeof(stl::MapLikeStruct);
  return size;
}
template <class Map>
unsigned sizeOfMapS (Map& map)
{
  unsigned size = 0;
  for (typename Map::iterator it=map.begin(); it!=map.end(); it++)
  {
    typename Map::mapped_type& T = it->second;
    size += sizeof(T);
  }
  size += map.size() * sizeof(stl::MapLikeStruct);
  return size;
}

#if defined(WIN32) || defined(WIN64)
#	define VOLUMETRIC_FOG_SHADOWS
#endif

#include <Cry_Math.h>
#include <Cry_Geo.h>
//#include "_Malloc.h"
//#include "math.h"
#include <StlUtils.h>
#include "XRenderD3D9/DeviceManager/DeviceManager.h"

#include <VertexFormats.h>

#include "Common/CommonRender.h"
#include <IRenderAuxGeom.h>
#include "Common/Shaders/ShaderComponents.h"
#include "Common/Shaders/Shader.h"
//#include "Common/XFile/File.h"
//#include "Common/Image.h"
#include "Common/Shaders/CShader.h"
#include "Common/DevBuffer.h"
#include "Common/RenderMesh.h"
#include "Common/RenderPipeline.h"
#include "Common/RenderThread.h"
#include "Common/Renderer.h"
#include "Common/Textures/Texture.h"
#include "Common/Shaders/Parser.h"
#include "Common/FrameProfiler.h"
#include "Common/Shadow_Renderer.h"
#include "Common/DeferredRenderUtils.h"
#include "Common/ShadowUtils.h"
#include "Common/WaterUtils.h"

#include "Common/OcclQuery.h"

// All handled render elements (except common ones included in "RendElement.h")
#include "Common/RendElements/CREBeam.h"
#include "Common/RendElements/CREClientPoly.h"
#include "Common/RendElements/CREFlares.h"
#include "Common/RendElements/CREHDRProcess.h"
#include "Common/RendElements/CRECloud.h"
#include "Common/RendElements/CREDeferredShading.h"

#include "Common/PostProcess/PostProcess.h"

class CREMeshImpl : public CREMesh
{
#if defined(DIRECT3D10) && !defined(PS3) && !defined(CAFE)
public:
	// Constant buffer used for tessellation. It has just one constant which tells the hull shader how it needs to offset iPrimitiveID that comes from HW.
	WrappedDX11Buffer m_tessCB;
#endif

public:
	virtual struct CRenderChunk *mfGetMatInfo();
	virtual PodArray<struct CRenderChunk> *mfGetMatInfoList();
	virtual int mfGetMatId();
	virtual bool mfPreDraw(SShaderPass *sl);
	virtual bool mfIsHWSkinned()
	{
		return ( m_Flags & FCEF_SKINNED ) != 0;
	}
	virtual void mfGetPlane(Plane& pl);
	virtual void mfPrepare(bool bCheckOverflow);
	virtual void mfReset();
	virtual void mfCenter(Vec3& Pos, CRenderObject*pObj);
	virtual bool mfDraw(CShader *ef, SShaderPass *sfm);
	virtual void *mfGetPointer(ESrcPointer ePT, int *Stride, EParamType Type, ESrcPointer Dst, int Flags);
	virtual float mfDistanceToCameraSquared(Matrix34& matInst);
	virtual bool mfUpdate(EVertexFormat eVertFormat, int Flags, bool bTessellation = false);
	virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs);
	virtual void mfPrecache(const SShaderItem& SH);
	virtual int Size()
	{
		int nSize = sizeof(*this);
		return nSize;
	}
	virtual void GetMemoryUsage(ICrySizer *pSizer) const
	{
		pSizer->AddObject(this, sizeof(*this));
	}

	CREMeshImpl()
	{
	}

	virtual ~CREMeshImpl()
	{
	}

#if !defined(_RELEASE)
	inline bool ValidateDraw(EShaderType shaderType);
#endif

//protected:
//	CREMeshImpl(CREMeshImpl&);
//	CREMeshImpl& operator=(CREMeshImpl&);
};

/*-----------------------------------------------------------------------------
	Vector transformations.
-----------------------------------------------------------------------------*/

_inline void TransformVector(Vec3& out, const Vec3& in, const Matrix44A& m)
{
	out.x = in.x * m(0,0) + in.y * m(1,0) + in.z * m(2,0);
	out.y = in.x * m(0,1) + in.y * m(1,1) + in.z * m(2,1);
	out.z = in.x * m(0,2) + in.y * m(1,2) + in.z * m(2,2);
}

_inline void TransformPosition(Vec3& out, const Vec3& in, const Matrix44A& m)
{
	TransformVector (out, in, m);
	out += m.GetRow(3);
}


inline Plane TransformPlaneByUsingAdjointT( const Matrix44A& M, const Matrix44A& TA, const Plane plSrc)
{
	Vec3 newNorm;
	TransformVector (newNorm, plSrc.n, TA);
	newNorm.Normalize();

	if(M.Determinant() < 0.f)
		newNorm *= -1;

	Plane plane;
	Vec3 p;
	TransformPosition (p, plSrc.n * plSrc.d, M);
	plane.Set(newNorm, p | newNorm);

	return plane;
}

inline Matrix44 TransposeAdjoint(const Matrix44A& M)
{
	Matrix44 ta;

	ta(0,0) = M(1,1) * M(2,2) - M(2,1) * M(1,2);
	ta(1,0) = M(2,1) * M(0,2) - M(0,1) * M(2,2);
	ta(2,0) = M(0,1) * M(1,2) - M(1,1) * M(0,2);

	ta(0,1) = M(1,2) * M(2,0) - M(2,2) * M(1,0);
	ta(1,1) = M(2,2) * M(0,0) - M(0,2) * M(2,0);
	ta(2,1) = M(0,2) * M(1,0) - M(1,2) * M(0,0);

	ta(0,2) = M(1,0) * M(2,1) - M(2,0) * M(1,1);
	ta(1,2) = M(2,0) * M(0,1) - M(0,0) * M(2,1);
	ta(2,2) = M(0,0) * M(1,1) - M(1,0) * M(0,1);

	ta(0,3) = 0.f;
	ta(1,3) = 0.f;
	ta(2,3) = 0.f;


	return ta;
}

inline Plane TransformPlane( const Matrix44A& M, const Plane& plSrc)
{
	Matrix44 tmpTA = TransposeAdjoint(M);
	return TransformPlaneByUsingAdjointT(M, tmpTA, plSrc);
}

// Homogeneous plane transform.
inline Plane TransformPlane2(const Matrix34A& m, const Plane& src)
{
	Plane plDst;

	float v0=src.n.x, v1=src.n.y, v2=src.n.z, v3=src.d;
	plDst.n.x = v0 * m(0,0) + v1 * m(1,0) + v2 * m(2,0);
	plDst.n.y = v0 * m(0,1) + v1 * m(1,1) + v2 * m(2,1);
	plDst.n.z = v0 * m(0,2) + v1 * m(1,2) + v2 * m(2,2);

	plDst.d = v0 * m(0,3) + v1 * m(1,3) + v2 * m(2,3) + v3;

	return plDst;
}

// Homogeneous plane transform.
inline Plane TransformPlane2(const Matrix44A& m, const Plane& src)
{
	Plane plDst;

	float v0=src.n.x, v1=src.n.y, v2=src.n.z, v3=src.d;
	plDst.n.x = v0 * m(0,0) + v1 * m(0,1) + v2 * m(0,2) + v3 * m(0,3);
	plDst.n.y = v0 * m(1,0) + v1 * m(1,1) + v2 * m(1,2) + v3 * m(1,3);
	plDst.n.z = v0 * m(2,0) + v1 * m(2,1) + v2 * m(2,2) + v3 * m(2,3);

	plDst.d = v0 * m(3,0) + v1 * m(3,1) + v2 * m(3,2) + v3 * m(3,3);

	return plDst;
}
inline Plane TransformPlane2_NoTrans(const Matrix44A& m, const Plane& src )
{
	Plane plDst;
	TransformVector(plDst.n, src.n, m);
	plDst.d = src.d;

	return plDst;
}

inline Plane TransformPlane2Transposed(const Matrix44A& m, const Plane& src )
{
	Plane plDst;

	float v0=src.n.x, v1=src.n.y, v2=src.n.z, v3=src.d;
	plDst.n.x = v0 * m(0,0) + v1 * m(1,0) + v2 * m(2,0) + v3 * m(3,0);
	plDst.n.y = v0 * m(0,1) + v1 * m(1,1) + v2 * m(2,1) + v3 * m(3,1);
	plDst.n.z = v0 * m(0,2) + v1 * m(2,1) + v2 * m(2,2) + v3 * m(3,2);

	plDst.d   = v0 * m(0,3) + v1 * m(1,3) + v2 * m(2,3) + v3 * m(3,3);

	return plDst;
}

//===============================================================================================

#define MAX_PATH_LENGTH	512

#if !defined(LINUX) && !defined(PS3) && !defined(CAFE)	//than it does already exist
inline int vsnprintf(char * buf, int size, const char * format, va_list & args)
{
	int res = _vsnprintf_s(buf, size,size, format, args);
	assert(res>=0 && res<size); // just to know if there was problems in past
	buf[size-1]=0;
	return res;
}
#endif

#if !defined(LINUX) && !defined(PS3) && !defined(CAFE)
inline int snprintf(char * buf, int size, const char * format, ...)
{
	va_list arglist;
	va_start(arglist, format);
	int res = _vsnprintf_s(buf, size,size, format, arglist);
	va_end(arglist);	
	return res;
}
#endif

//////////////////////////////////////////////////////////////////////////
// Report warning to validator.
//////////////////////////////////////////////////////////////////////////
inline void Warning( const char *format,... ) PRINTF_PARAMS(1, 2);
inline void Warning( const char *format,... )
{
	va_list args;
	va_start(args, format);
	if (iSystem)
		iSystem->WarningV( VALIDATOR_MODULE_RENDERER,VALIDATOR_WARNING,0,NULL,format,args );
	va_end(args);
}

//////////////////////////////////////////////////////////////////////////
// Report warning to validator.
//////////////////////////////////////////////////////////////////////////
inline void LogWarning( const char *format,... ) PRINTF_PARAMS(1, 2);
inline void LogWarning( const char *format,... )
{
	va_list args;
	va_start(args, format);
	if (iSystem)
		iSystem->WarningV( VALIDATOR_MODULE_RENDERER,VALIDATOR_WARNING,0,NULL,format,args );
	va_end(args);
}

//////////////////////////////////////////////////////////////////////////
// Report warning to validator.
//////////////////////////////////////////////////////////////////////////
inline void FileWarning( const char*filename,const char *format,... ) PRINTF_PARAMS(2, 3);
inline void FileWarning( const char*filename,const char *format,... )
{
	va_list args;
	va_start(args, format);
	if (iSystem)
		iSystem->WarningV( VALIDATOR_MODULE_RENDERER,VALIDATOR_WARNING,VALIDATOR_FLAG_FILE,filename,format,args );
	va_end(args);
}

//////////////////////////////////////////////////////////////////////////
// Report warning to validator.
//////////////////////////////////////////////////////////////////////////
inline void TextureWarning( const char *filename,const char *format,... ) PRINTF_PARAMS(2, 3);
inline void TextureWarning( const char *filename,const char *format,... )
{
	va_list args;
	va_start(args, format);
	if (iSystem)
		iSystem->WarningV( VALIDATOR_MODULE_RENDERER,VALIDATOR_WARNING, (VALIDATOR_FLAG_FILE|VALIDATOR_FLAG_TEXTURE), filename,format,args );
	va_end(args);
}

inline void TextureError( const char *filename,const char *format,... )
{
	va_list args;
	va_start(args, format);
	if (iSystem)
		iSystem->WarningV( VALIDATOR_MODULE_RENDERER,VALIDATOR_ERROR, (VALIDATOR_FLAG_FILE|VALIDATOR_FLAG_TEXTURE), filename,format,args );
	va_end(args);
}

_inline void _SetVar(const char *szVarName, int nVal)
{
	ICVar *var = iConsole->GetCVar(szVarName);
	if (var)
		var->Set(nVal);
	else
	{
		assert(0);
	}
}

const char* fpGetExtension (const char *in);
void fpStripExtension (const char *in, char *out);
void fpAddExtension (char *path, char *extension);
void fpConvertDOSToUnixName( char *dst, const char *src );
void fpConvertUnixToDosName( char *dst, const char *src );
void fpUsePath (char *name, char *path, char *dst);

//=========================================================================================
//
// Normal timing.
//
#define ticks(Timer)   {Timer -= CryGetTicks();}
#define unticks(Timer) {Timer += CryGetTicks()+34;}

//=============================================================================

// the int 3 call for 32-bit version for .l-generated files.
#ifdef WIN64
#define LEX_DBG_BREAK
#else
#define LEX_DBG_BREAK DEBUG_BREAK
#endif

#include "Common/Defs.h"

#define FUNCTION_PROFILER_RENDERER FUNCTION_PROFILER_FAST( iSystem, PROFILE_RENDERER, g_bProfilerEnabled )








#define SCOPED_RENDERER_ALLOCATION_NAME_HINT( str )


#if (defined (WIN32) || defined(XENON)) && !defined(PS3)
	#define SHADER_ASYNC_COMPILATION
#endif

/*-----------------------------------------------------------------------------
	The End.
-----------------------------------------------------------------------------*/
#endif
